﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using BoxSharp;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;

namespace BoxSharpToolButton
{
    public class BoxSharpToolButton : AddonInstance
    {
        private AddonInterface myInterface = null;
        private StackPanel toolPanel = null;
        private string buttonConfig = "";
        private Dictionary<string, ToolCommand> toolButtons = new Dictionary<string, ToolCommand>();
        private ToolTip tip = null;
        private Regex chkAdd = new Regex("/toolbutton add \"(?<face>[^\"]+)\" (?<command>.+)", RegexOptions.IgnoreCase);
        private Regex chkDel = new Regex("/toolbutton remove \"(?<face>[^\"]+)\"", RegexOptions.IgnoreCase);

        public override void AddonMain(AddonInterface addonInterface)
        {
            myInterface = addonInterface;

            myInterface.AddonInitializing += new AddonEventHandler(myInterface_AddonInitializing);
            myInterface.AddonFinalizing += new AddonEventHandler(myInterface_AddonFinalizing);
        }

        void myInterface_AddonFinalizing()
        {
            myInterface.Panel2.Children.Remove(toolPanel);

            StreamWriter writer = new StreamWriter(buttonConfig);
            foreach (ToolCommand commander in toolButtons.Values)
            {
                writer.WriteLine(commander.ButtonFace);
                writer.WriteLine(commander.Command);
            }
            writer.Close();
        }

        void myInterface_AddonInitializing()
        {
            buttonConfig = Path.Combine(myInterface.Path, "buttons.txt");

            toolPanel = new StackPanel();
            toolPanel.Orientation = Orientation.Horizontal;

            tip = new System.Windows.Controls.ToolTip();
            tip.HasDropShadow = true;
            tip.PlacementTarget = myInterface.Box;
            tip.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            tip.IsOpen = false;
            tip.Padding = new System.Windows.Thickness(5);
            tip.VerticalOffset = 5;
            tip.Content = "/toolbutton add \"button name\" command\r\nAdd a button named \"button name\" to the tool bar, this button will execute \"command\" when clicked.\r\nFor example:/toolbutton add \"hello\" /script MessageBox.Show(\"Hello!\");\r\n\r\n/toolbutton remove \"button name\"\r\nRemove the button named \"button name\".";

            myInterface.Panel2.Children.Add(toolPanel);

            if (!File.Exists(buttonConfig))
            {
                StreamWriter creater = new StreamWriter(buttonConfig);
                creater.Close();
            }

            StreamReader reader = new StreamReader(buttonConfig);
            while (reader.Peek() > -1)
            {
                string face = reader.ReadLine();
                string command = reader.ReadLine();

                if (face == null || command == null || face.Length < 1 || command.Length < 1)
                {
                    break;
                }

                ToolCommand newCommander = new ToolCommand();
                newCommander.Button = new Button();
                newCommander.Button.Content = face;
                newCommander.Button.Tag = command;
                newCommander.Button.Margin = new Thickness(5, 0, 5, 0);
                newCommander.Button.Click += new RoutedEventHandler(Button_Click);
                toolPanel.Children.Add(newCommander.Button);

                newCommander.ButtonFace = face;
                newCommander.Command = command;

                if (!toolButtons.ContainsKey(face))
                {
                    toolButtons.Add(face, newCommander);
                }
            }
            reader.Close();

            myInterface.Box.TextChanged += new TextChangedEventHandler(Box_TextChanged);
            myInterface.OnCommand += new CommandEventHandler(myInterface_OnCommand);
        }

        void Button_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            string command = button.Tag as string;
            myInterface.SendCommand(command);
        }

        void myInterface_OnCommand(string bscommand)
        {
            Match m = chkAdd.Match(bscommand);
            if (m.Success)
            {
                string face = m.Groups["face"].Value;
                string command = m.Groups["command"].Value;

                if (toolButtons.ContainsKey(face))
                {
                    MessageBox.Show(face + " already exists in the tool bar!", "Information", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                ToolCommand newCommander = new ToolCommand();
                newCommander.Button = new Button();
                newCommander.Button.Content = face;
                newCommander.Button.Margin = new Thickness(5, 0, 5, 0);
                newCommander.Button.Tag = command;
                newCommander.Button.Click += new RoutedEventHandler(Button_Click);
                toolPanel.Children.Add(newCommander.Button);

                newCommander.ButtonFace = face;
                newCommander.Command = command;

                toolButtons.Add(face, newCommander);

                myInterface.Box.Text = "";
            }
            else
            {
                m = chkDel.Match(bscommand);

                if (m.Success)
                {
                    string face = m.Groups["face"].Value;

                    if (toolButtons.ContainsKey(face))
                    {
                        toolPanel.Children.Remove(toolButtons[face].Button);
                        toolButtons.Remove(face);
                    }
                    else
                    {
                        MessageBox.Show(face + " not found in the tool bar!", "Information", MessageBoxButton.OK, MessageBoxImage.Information);
                        return;
                    }

                    myInterface.Box.Text = "";
                }
            }
        }

        void Box_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (myInterface.Box.Text.ToLower().StartsWith("/toolbutton"))
            {
                tip.IsOpen = true;
            }
            else
            {
                tip.IsOpen = false;
            }
        }
    }

    class ToolCommand
    {
        public string ButtonFace;
        public string Command;
        public Button Button;
    }
}
